#include "semaphore.h"

/*
 * Call wait() on a semaphore. The count is
 * first decremented, then if the count is less
 * than 0, that process is added to the semaphore
 * queue from the brain10 VMs ready queue
 * @param sem A semaphore to decrement
 */
int wait(semaphore* sem){
	sem->count--;
	if(sem->count < 0){
#ifdef DEBUG
		printf("Adding process %s to semaphore queue\n",process_ready_queue->head->data->PID);
#endif
		/* save reference to this process to increment
		 * its IC so that it doesn't call wait again when
		 * it is placed back into the ready queue
		 */
		node* proc = pop(process_ready_queue);
		pcb* block = (pcb*)proc->data;
		int ic = atoi(block->IC);
		snprintf(block->IC, 3, "%.2i", ic+1);

		/* add the process to the semaphores queue */
		append(&sem->q, 0, proc);
		sem->size++;

		return 1;
	}
	return 0; //process did not have to wait
}

/*
 * Call signal() on a semaphore. The count is
 * first incremented, then if the count is >= 0,
 * the next process waiting in line is removed from the
 * queue and allowed to continue its execution.
 * @param sem A semaphore to increment
 */
void sig(semaphore* sem){
	sem->count++;
	if(sem->q.length > 0){// && sem->count >= 0){
#ifdef DEBUG
		printf("Removing process %s from semaphore queue\n",sem->q.head->data->PID);
#endif
		append(process_ready_queue, 0, pop(&sem->q) );
		sem->size--;
	}
}

/*
 * Set the count of the semaphore
 * @param sem A semaphore
 * @param value The new value of the semaphore's count
 */
void initialize(semaphore* sem, int value){
	sem->count = value;
}

/*
 * print out the processes currently waiting in a
 * semaphore's queue
 * @param sem The semaphore's queue to use
 */
void printSemaphore(semaphore* sem){
	printf("Semaphore Queue: \n");
	printList(&sem->q);
}
